package com.oig.sys.workflow.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.oig.common.exception.BadRequestException;
import com.oig.sys.workflow.constants.FlowEnums;
import com.oig.sys.workflow.dao.ITbFlowInstanceDao;
import com.oig.sys.workflow.dto.FlowInstanceDto;
import com.oig.sys.workflow.entity.TbFlowInstance;
import com.oig.sys.workflow.service.ITbFlowInstanceService;

import com.oig.sys.workflow.vo.FlowInstanceVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * @author wuxl
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TbFlowInstanceServiceImpl implements ITbFlowInstanceService {

	private final ITbFlowInstanceDao tbFlowInstanceDao;


	@Transactional
	@Override
	public FlowInstanceVo addOrUpdate(FlowInstanceDto flowInstanceDto) {
		int size = this.tbFlowInstanceDao.countBizFlow(flowInstanceDto.getBizType(), flowInstanceDto.getBizId(), FlowEnums.InstanceStatus.PENDING.getCode());
		if (size>0){
			log.error("已存在审批单");
			throw new BadRequestException("审批单已提交，请勿重复提交");
		}
		TbFlowInstance flowInstance = this.tbFlowInstanceDao.getInitBizFlow(flowInstanceDto.getBizType(), flowInstanceDto.getBizId());
		if (flowInstance!=null){
			log.debug("update reReq..old:{}",flowInstance.getFlowInstanceId());
			flowInstance.setFlowConfigId(flowInstanceDto.getFlowConfigId());
			flowInstance.setFlowCode(flowInstanceDto.getFlowCode());
			flowInstance.setFlowName(flowInstanceDto.getFlowName());
			flowInstance.setSysCode(flowInstanceDto.getSysCode());
			flowInstance.setTenantId(flowInstanceDto.getTenantId());
			flowInstance.setTenantName(flowInstanceDto.getTenantName());
			flowInstance.setBizType(flowInstanceDto.getBizType());
			flowInstance.setBizId(flowInstanceDto.getBizId());
			flowInstance.setLastUpdateCode(flowInstanceDto.getCreateUserCode());
			flowInstance.setFlowData(flowInstanceDto.getFlowData());
		} else {
			log.debug("create new req 一个业务单据可以提交多次审批");
			flowInstance = BeanUtil.copyProperties(flowInstanceDto, TbFlowInstance.class);
			flowInstance.setStatus(FlowEnums.FlowStatus.REQ_INIT.getCode());
			flowInstance.setFlowReqNum(0);
			flowInstance.setNotifyStatus(FlowEnums.NotifyStatus.INIT.getCode());
			flowInstance.setNotifyNum(0);
			flowInstance.setCreateTime(new Date());
			flowInstance.setLastUpdateTime(flowInstance.getCreateTime());
			flowInstance.setLastUpdateCode(flowInstance.getCreateUserCode());
		}
		this.tbFlowInstanceDao.save(flowInstance);
		return BeanUtil.copyProperties(flowInstance, FlowInstanceVo.class);
	}

	@Transactional
	@Override
	public void updateSubResult(Integer id, String instanceId, String rspMsg) {
		TbFlowInstance instance = this.tbFlowInstanceDao.getTbFlowInstanceById(id);
		if(instanceId!=null){
			instance.setStatus(FlowEnums.FlowStatus.PUSHED.getCode());
			instance.setFlowInstanceStatus(FlowEnums.InstanceStatus.PENDING.getCode());
			instance.setFlowInstanceId(instanceId);
		}
		instance.setFlowReqNum(instance.getFlowReqNum()+1);
		instance.setFlowReqTime(new Date());
		instance.setFlowReqMsg(rspMsg);
		this.tbFlowInstanceDao.save(instance);
	}

	@Transactional
	@Override
	public FlowInstanceVo cancelFlowByBiz(String bizType, String bizId) {
		TbFlowInstance flowInstance = this.tbFlowInstanceDao.getInitBizFlow(bizType, bizId);
		if (flowInstance!=null){
			flowInstance.setStatus(FlowEnums.FlowStatus.CANCELED.getCode());
			flowInstance.setNotifyStatus(FlowEnums.NotifyStatus.UN_NEED.getCode());
			this.tbFlowInstanceDao.save(flowInstance);
		} else {
			flowInstance = this.tbFlowInstanceDao.getPnBizFlow(bizType, bizId);
			if (flowInstance==null) return null;
			flowInstance.setStatus(FlowEnums.FlowStatus.CAN_INIT.getCode());
			flowInstance.setNotifyStatus(FlowEnums.NotifyStatus.UN_NEED.getCode());
			this.tbFlowInstanceDao.save(flowInstance);
		}
		return BeanUtil.copyProperties(flowInstance, FlowInstanceVo.class);
	}

	@Transactional
	@Override
	public void doCancel(Integer id) {
		TbFlowInstance instance = this.tbFlowInstanceDao.getTbFlowInstanceById(id);
		instance.setFlowInstanceStatus(FlowEnums.InstanceStatus.CANCELED.getCode());
		instance.setStatus(FlowEnums.FlowStatus.CANCELED.getCode());
		this.tbFlowInstanceDao.save(instance);
	}

	@Override
	public FlowInstanceVo getFlowByBiz(String bizType, String bizId) {
		TbFlowInstance flowInstance = this.tbFlowInstanceDao.getBizFlow(bizType, bizId);
		if (flowInstance==null) return null;
		return BeanUtil.copyProperties(flowInstance, FlowInstanceVo.class);
	}

	@Transactional
	@Override
	public FlowInstanceVo updateFlowInstanceStatus(String flowCode, String instanceId, String instanceStatus) {
		TbFlowInstance flowInstance = this.tbFlowInstanceDao.getByFlowCodeAndFlowInstanceId(flowCode, instanceId);
		if (flowInstance==null) return null;
		if (FlowEnums.InstanceStatus.PENDING.getCode().equals(flowInstance.getFlowInstanceStatus())){
			flowInstance.setNotifyStatus(FlowEnums.NotifyStatus.PENDING.getCode());
			flowInstance.setFlowInstanceStatus(instanceStatus);
			flowInstance.setLastUpdateTime(new Date());
			this.tbFlowInstanceDao.save(flowInstance);
		}
		return BeanUtil.copyProperties(flowInstance, FlowInstanceVo.class);
	}

	@Transactional
	@Override
	public void updateNotifyStatus(Integer id, String notifyStatus) {
		TbFlowInstance flowInstance = this.tbFlowInstanceDao.getTbFlowInstanceById(id);
		flowInstance.setNotifyStatus(notifyStatus);
		if (!FlowEnums.NotifyStatus.UN_NEED.getCode().equals(notifyStatus)){
			flowInstance.setNotifyNum(flowInstance.getNotifyNum()+1);
			flowInstance.setLastNotifyTime(new Date());
		}
		this.tbFlowInstanceDao.save(flowInstance);
	}


	@Override
	public FlowInstanceVo getById(Integer id) {
		TbFlowInstance flowInstance = this.tbFlowInstanceDao.getTbFlowInstanceById(id);
		return BeanUtil.copyProperties(flowInstance, FlowInstanceVo.class);
	}

}
